import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
import { ElNotification } from 'element-plus'

// 定义接口返回数据的类型
interface ApiResponse<T = any> {
  code: number
  message: string
  data: T
}

class Request {
  private instance: AxiosInstance

  constructor(baseURL: string, timeout = 10000) {
    this.instance = axios.create({
      baseURL,
      timeout
    })

    // 请求拦截器
    this.instance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        // 在这里可以添加请求前的逻辑，例如添加 token
        const token = localStorage.getItem('token')
        if (token) {
          config.headers.Authorization = `Bearer ${token}`
        }
        return config
      },
      (error) => {
        return Promise.reject(error)
      }
    )

    // 响应拦截器
    this.instance.interceptors.response.use(
      (response: AxiosResponse<ApiResponse>) => {
        // 在这里可以处理响应数据
        const { data } = response
        if (data.code === 200) {
          return data
        } else {
          // 处理业务错误
          ElNotification({
            title: '发生异常',
            message: data.message,
            type: 'error'
          })
          return Promise.reject(new Error(data.message || 'Error'))
        }
      },
      (error) => {
        // 处理 HTTP 错误
        if (error.response) {
          switch (error.response.status) {
            case 404:
              // 处理资源不存在
              ElNotification({
                title: '请求异常',
                message: '404 NOT FOUND，请求资源不存在！',
                type: 'error'
              })
              break
            case 500:
              // 处理服务器错误
              ElNotification({
                title: '发生异常',
                message: '服务出小差了，请联系管理员！',
                type: 'error'
              })
              break
            default:
              break
          }
        }
        return Promise.reject(error)
      }
    )
  }

  // 封装请求方法
  public get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.get(url, config)
  }

  public post<T>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.post(url, data, config)
  }

  public put<T>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.put(url, data, config)
  }

  public delete<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.delete(url, config)
  }
}

// 根据环境变量获取 baseURL
const baseURL =  '/api'

// 创建请求实例
const request = new Request(baseURL)

export default request
